//////////////////////////////////////////////////////////////////////////
#pragma once


//////////////////////////////////////////////////////////////////////////
#include "Config.hpp"


//////////////////////////////////////////////////////////////////////////
// Per compiler macro's.
#if defined( COMPILER_MSVC ) || defined( COMPILER_INTEL )

#	define BEGIN_ALIGNED( n, a )				__declspec( align( a ) ) n
#	define END_ALIGNED( n, a )

#elif defined( COMPILER_GNU ) || defined( COMPILER_CLANG )

#	define BEGIN_ALIGNED( n, a )				n
#	define END_ALIGNED( n, a )					__attribute__( (aligned( a ) ) )

#endif


//////////////////////////////////////////////////////////////////////////
//	Aligned memory utilities.
#	if _WINDOWS
#		define CORE_ALIGNED_ALLOC( s, a )		_aligned_malloc( s, a )
#		define CORE_ALIGNED_FREE( p )			_aligned_free( p )
#	else
#		define CORE_ALIGNED_ALLOC( s, a )		malloc( s )
#		define CORE_ALIGNED_FREE( p )			free( p )
#	endif


//////////////////////////////////////////////////////////////////////////
//	Helper to override new/delete with aligned versions.
#	define ALIGNED_MEMORY( c, a )											\
		void*	operator new( size_t size ) {								\
		return CORE_ALIGNED_ALLOC( size, a ); }								\
		void*	operator new( size_t size, void* b ) {						\
		return b;}															\
		void*	operator new[]( size_t size ) {								\
		return CORE_ALIGNED_ALLOC( size, a ); }								\
		void	operator delete( void* p ) {								\
		CORE_ALIGNED_FREE( p ); }											\
		void	operator delete[]( void* p ) {								\
		CORE_ALIGNED_FREE( p );}											\
		void	operator delete( void*, void* ) {							\
		}

//////////////////////////////////////////////////////////////////////////
// Generic macro's.
#define CONCAT_TOKEN_BASE( a, b )	a ## b
#define CONCAT_TOKEN( a, b )		CONCAT_TOKEN_BASE( a, b )


//////////////////////////////////////////////////////////////////////////
// Helper to cause unconditional break points, even in release builds.
#if defined( OS_WINDOWS )
#	define	CORE_BREAK		__debugbreak()
#else
#	include <signal.h>
#	define	CORE_BREAK		raise( SIGTRAP )
#endif



//////////////////////////////////////////////////////////////////////////
// Include flags and logging for everyone.
// Also deals with the Windows.h header.
#if defined( OS_WINDOWS )
#	if !defined( WIN32_LEAN_AND_MEAN )
#		define WIN32_LEAN_AND_MEAN
#	endif
#	include <Windows.h>
#	undef ERROR
#	undef min
#	undef max
#else
#endif

#include <assert.h>
#include <gflags/gflags.h>
#include <glog/logging.h>
